<?php
/*
 * @Description    : 阿里云语音短信发送
 * @Author         : QianLong
 * @Date           : 2023-01-19 21:50:04
 * @LastEditors    : QianLong
 * @Site           : http://www.21ds.cn
 * @LastEditTime   : 2024-01-16 17:05:40
 */

namespace App\Service\Sms;

use Yurun\Util\HttpRequest;

class AliVoice
{
    public function sendRequest($phone, $templateCode, $templateParam, $key_id,$key_secret, $CalledShowNumber = '', $OutId = '')
    {
        $smsParam['AccessKeyId'] = $key_id;
        $smsParam['Action'] = 'SingleCallByVoice';
        if (!empty($templateParam)) {
            $smsParam['Action'] = 'SingleCallByTts';
        }
        $smsParam['Format'] = 'JSON';
        $smsParam['CalledNumber'] = $phone;
        if (!empty($OutId)) {
            $smsParam['OutId'] = $OutId;
        }
        if (!empty($CalledShowNumber)) {
            $smsParam['CalledShowNumber'] = $CalledShowNumber;
        }
        $smsParam['SignatureMethod'] = 'HMAC-SHA1';
        $smsParam['SignatureNonce'] = createULId();
        $smsParam['SignatureVersion'] = '1.0';
        switch ($smsParam['Action']) {
            case 'SingleCallByVoice':
                $smsParam['VoiceCode'] = $templateCode;
                break;
            case 'SingleCallByTts':
                $smsParam['TtsCode'] = $templateCode;
                break;
        }
        
        if (!empty($templateParam)) {
            if (is_array($templateParam)) {
                $smsParam['TtsParam'] = json_encode($templateParam);
            } else {
                $templateParamArr = json_decode($templateParam,true);
                if (!empty($templateParamArr)) {
                    $smsParam['TtsParam'] = $templateParam;
                }
                unset($templateParamArr);
            }
        }
        $smsParam['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
        $smsParam['Version'] = '2017-05-25';
        $smsParam['Signature'] = $this->doSignature($smsParam, $key_secret);
        $requestParam = http_build_query($smsParam);
        $sendUrl = 'https://dyvmsapi.aliyuncs.com/?' . $requestParam;
        $http = new HttpRequest;
        $response = $http->get($sendUrl);
        $result = json_decode($response->body(), true);
        $postData['send_result'] = ($result['Code'] == 'OK') ? true : false;
        $postData['send_error'] = ($result['Code'] != 'OK') ? $result['Message'] : '';
        $postData['send_result_data'] = json_encode($result, JSON_UNESCAPED_UNICODE);
        $postData['smsParam'] = json_encode($smsParam, JSON_UNESCAPED_UNICODE);
        return $postData;
    }
    /**
     * ECS数据过滤
     * @param string $string
     * @return string
     * @author QianLong <87498106@qq.com>
     * @version 1.0.0
     * @date 2019-09-27 17:13:38
     */
    private static function charFilter($string)
    {
        // 使用urlencode编码后，将"+","*","%7E"做替换即满足ECS API规定的编码规范  
        $res = urlencode($string);
        $res = preg_replace('/\+/', '%20', $res);
        $res = preg_replace('/\*/', '%2A', $res);
        $res = preg_replace('/%7E/', '~', $res);
        return $res;
    }
    /**
     * 生成阿里签名
     * @param array $parameters
     * @param string $accessKeySecret
     * @return string
     * @author QianLong <87498106@qq.com>
     * @version 1.0.0
     * @date 2019-09-27 17:13:53
     */
    private function doSignature($parameters, $accessKeySecret)
    {
        // 将参数Key按字典顺序排序  
        ksort($parameters);
        // 生成规范化请求字符串  
        $canonicalizedQueryString = '';
        foreach ($parameters as $key => $value) {
            $canonicalizedQueryString .= '&' . self::charFilter($key)
                . '=' . self::charFilter($value);
        }
        // 生成用于计算签名的字符串 stringToSign  
        $stringToSign = 'GET&%2F&' . self::charFilter(substr($canonicalizedQueryString, 1));
        // 计算签名，注意accessKeySecret后面要加上字符'&'  
        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
        return $signature;
    }
}
